import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath } from 'url';
import { Document, Packer, Paragraph, TextRun, HeadingLevel, AlignmentType, BorderStyle, Table, TableRow, TableCell, WidthType, ImageRun, ExternalHyperlink, PageBreak, LineRuleType } from 'docx';
import { marked } from 'marked';
import * as cheerio from 'cheerio';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

class EnhancedMarkdownToWordConverter {
    constructor() {
        this.outputDir = path.join(__dirname, 'output');
        this.ensureOutputDir();
    }

    /**
     * 确保输出目录存在
     */
    ensureOutputDir() {
        if (!fs.existsSync(this.outputDir)) {
            fs.mkdirSync(this.outputDir, { recursive: true });
        }
    }

    /**
     * 转换单个Markdown文件为Word文档
     * @param {string} mdFilePath - Markdown文件路径
     * @param {string} outputFileName - 输出文件名（不含扩展名）
     */
    async convertFile(mdFilePath, outputFileName = null) {
        try {
            console.log(`🔄 正在转换: ${mdFilePath}`);
            
            // 读取Markdown文件
            const mdContent = await fs.readFile(mdFilePath, 'utf-8');
            
            // 处理VitePress特定的语法
            const processedContent = this.processVitePressContent(mdContent);
            
            // 转换为HTML
            const htmlContent = this.markdownToHtml(processedContent);
            
            // 生成Word文档
            const doc = this.createWordDocument(htmlContent, path.basename(mdFilePath, '.md'));
            
            // 确定输出文件名
            const fileName = outputFileName || path.basename(mdFilePath, '.md');
            const outputPath = path.join(this.outputDir, `${fileName}.docx`);
            
            // 生成并保存文档
            const buffer = await Packer.toBuffer(doc);
            await fs.writeFile(outputPath, buffer);
            
            console.log(`✅ 转换完成: ${outputPath}`);
            return outputPath;
            
        } catch (error) {
            console.error(`❌ 转换失败: ${mdFilePath}`, error);
            throw error;
        }
    }

    /**
     * 批量转换目录下的所有Markdown文件
     * @param {string} inputDir - 输入目录路径
     * @param {string} outputDir - 输出目录路径（可选）
     */
    async convertDirectory(inputDir, outputDir = null) {
        if (outputDir) {
            this.outputDir = outputDir;
            this.ensureOutputDir();
        }

        const files = this.getMarkdownFiles(inputDir);
        console.log(`📁 找到 ${files.length} 个Markdown文件`);

        const results = [];
        for (const file of files) {
            try {
                const outputPath = await this.convertFile(file);
                results.push({ input: file, output: outputPath, status: 'success' });
            } catch (error) {
                results.push({ input: file, output: null, status: 'error', error: error.message });
            }
        }

        console.log(`📊 转换完成: ${results.filter(r => r.status === 'success').length}/${results.length} 成功`);
        return results;
    }

    /**
     * 处理VitePress特定的语法
     * @param {string} content - Markdown内容
     * @returns {string} 处理后的内容
     */
    processVitePressContent(content) {
        let processed = content;

        // 处理 ::: tip 语法
        processed = processed.replace(/::: tip\s*([\s\S]*?)\n([\s\S]*?):::/g, (match, title, content) => {
            return `> **💡 ${title.trim()}**\n> ${content.trim()}`;
        });

        // 处理 ::: info 语法
        processed = processed.replace(/::: info\s*([\s\S]*?)\n([\s\S]*?):::/g, (match, title, content) => {
            return `> **ℹ️ ${title.trim()}**\n> ${content.trim()}`;
        });

        // 处理 ::: warning 语法
        processed = processed.replace(/::: warning\s*([\s\S]*?)\n([\s\S]*?):::/g, (match, title, content) => {
            return `> **⚠️ ${title.trim()}**\n> ${content.trim()}`;
        });

        // 处理代码块中的语言标识
        processed = processed.replace(/```(\w+)\n/g, '```\n');

        return processed;
    }

    /**
     * 将Markdown转换为HTML
     * @param {string} markdown - Markdown内容
     * @returns {string} HTML内容
     */
    markdownToHtml(markdown) {
        // 配置marked选项
        marked.setOptions({
            breaks: true,
            gfm: true,
            headerIds: false
        });

        return marked(markdown);
    }

    /**
     * 创建Word文档
     * @param {string} html - HTML内容
     * @param {string} title - 文档标题
     * @returns {Document} Word文档对象
     */
    createWordDocument(html, title) {
        const $ = cheerio.load(html);
        const children = [];

        // 添加文档标题
        children.push(
            new Paragraph({
                text: title,
                heading: HeadingLevel.HEADING_1,
                alignment: AlignmentType.CENTER,
                spacing: {
                    after: 400,
                    before: 400
                }
            })
        );

        // 处理所有元素
        $('body').children().each((i, elem) => {
            const element = this.processElement($, elem);
            if (element) {
                children.push(element);
            }
        });

        return new Document({
            sections: [{
                properties: {
                    page: {
                        margin: {
                            top: 1440,
                            right: 1440,
                            bottom: 1440,
                            left: 1440
                        }
                    }
                },
                children: children
            }]
        });
    }

    /**
     * 处理HTML元素
     * @param {Object} $ - Cheerio对象
     * @param {Object} elem - HTML元素
     * @returns {Paragraph|Table|null} Word文档元素
     */
    processElement($, elem) {
        const tagName = elem.name;
        const text = $(elem).text().trim();

        switch (tagName) {
            case 'h1':
                return new Paragraph({
                    text: text,
                    heading: HeadingLevel.HEADING_1,
                    spacing: { after: 300, before: 300 }
                });

            case 'h2':
                return new Paragraph({
                    text: text,
                    heading: HeadingLevel.HEADING_2,
                    spacing: { after: 240, before: 240 }
                });

            case 'h3':
                return new Paragraph({
                    text: text,
                    heading: HeadingLevel.HEADING_3,
                    spacing: { after: 200, before: 200 }
                });

            case 'h4':
            case 'h5':
            case 'h6':
                return new Paragraph({
                    text: text,
                    heading: HeadingLevel.HEADING_4,
                    spacing: { after: 180, before: 180 }
                });

            case 'p':
                if (text) {
                    // 检查是否是引用块
                    if ($(elem).find('> strong').length > 0) {
                        return new Paragraph({
                            children: [
                                new TextRun({
                                    text: text,
                                    bold: true,
                                    color: '2E86AB'
                                })
                            ],
                            spacing: { after: 200, before: 200 },
                            indent: { left: 720 }
                        });
                    }
                    
                    return new Paragraph({
                        text: text,
                        spacing: { after: 200, before: 200 }
                    });
                }
                break;

            case 'ul':
            case 'ol':
                return this.processList($, elem);

            case 'pre':
                return this.processCodeBlock($, elem);

            case 'table':
                return this.processTable($, elem);

            case 'blockquote':
                return new Paragraph({
                    text: text,
                    spacing: { after: 200, before: 200 },
                    indent: { left: 720 },
                    border: {
                        left: {
                            color: 'CCCCCC',
                            space: 1,
                            style: BorderStyle.SINGLE,
                            size: 6
                        }
                    }
                });

            case 'hr':
                return new Paragraph({
                    children: [
                        new TextRun({
                            text: '─'.repeat(50),
                            color: 'CCCCCC'
                        })
                    ],
                    alignment: AlignmentType.CENTER,
                    spacing: { after: 300, before: 300 }
                });
        }

        return null;
    }

    /**
     * 处理列表
     * @param {Object} $ - Cheerio对象
     * @param {Object} elem - 列表元素
     * @returns {Array} 段落数组
     */
    processList($, elem) {
        const paragraphs = [];
        const isOrdered = elem.name === 'ol';

        $(elem).find('li').each((i, li) => {
            const text = $(li).text().trim();
            const bulletText = isOrdered ? `${i + 1}.` : '•';
            
            paragraphs.push(
                new Paragraph({
                    children: [
                        new TextRun({
                            text: `${bulletText} `,
                            bold: true
                        }),
                        new TextRun({
                            text: text
                        })
                    ],
                    spacing: { after: 120, before: 120 },
                    indent: { left: 720 }
                })
            );
        });

        return paragraphs;
    }

    /**
     * 处理代码块
     * @param {Object} $ - Cheerio对象
     * @param {Object} elem - 代码块元素
     * @returns {Paragraph} 代码块段落
     */
    processCodeBlock($, elem) {
        const code = $(elem).text();
        
        return new Paragraph({
            children: [
                new TextRun({
                    text: code,
                    font: 'Courier New',
                    size: 20
                })
            ],
            spacing: { after: 200, before: 200 },
            indent: { left: 720, right: 720 },
            border: {
                top: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                bottom: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                left: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                right: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 }
            },
            shading: {
                fill: 'F8F9FA'
            }
        });
    }

    /**
     * 处理表格
     * @param {Object} $ - Cheerio对象
     * @param {Object} elem - 表格元素
     * @returns {Table} 表格对象
     */
    processTable($, elem) {
        const rows = [];
        
        $(elem).find('tr').each((i, row) => {
            const cells = [];
            $(row).find('td, th').each((j, cell) => {
                const text = $(cell).text().trim();
                const isHeader = cell.name === 'th';
                
                cells.push(
                    new TableCell({
                        children: [
                            new Paragraph({
                                children: [
                                    new TextRun({
                                        text: text,
                                        bold: isHeader,
                                        color: isHeader ? 'FFFFFF' : '000000'
                                    })
                                ],
                                alignment: AlignmentType.CENTER
                            })
                        ],
                        width: {
                            size: 2000,
                            type: WidthType.DXA
                        },
                        shading: isHeader ? {
                            fill: '2E86AB'
                        } : undefined,
                        borders: {
                            top: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                            bottom: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                            left: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 },
                            right: { color: 'CCCCCC', space: 1, style: BorderStyle.SINGLE, size: 6 }
                        }
                    })
                );
            });
            
            rows.push(new TableRow({ children: cells }));
        });

        return new Table({
            rows: rows,
            width: {
                size: 100,
                type: WidthType.PERCENTAGE
            }
        });
    }

    /**
     * 获取目录下的所有Markdown文件
     * @param {string} dir - 目录路径
     * @returns {Array} Markdown文件路径数组
     */
    getMarkdownFiles(dir) {
        const files = [];
        
        function scanDirectory(currentDir) {
            const items = fs.readdirSync(currentDir);
            
            for (const item of items) {
                const fullPath = path.join(currentDir, item);
                const stat = fs.statSync(fullPath);
                
                if (stat.isDirectory()) {
                    // 跳过node_modules和.git目录
                    if (item !== 'node_modules' && item !== '.git' && item !== 'output') {
                        scanDirectory(fullPath);
                    }
                } else if (item.endsWith('.md')) {
                    files.push(fullPath);
                }
            }
        }
        
        scanDirectory(dir);
        return files;
    }
}

// 使用示例
async function main() {
    const converter = new EnhancedMarkdownToWordConverter();
    
    // 示例1: 转换单个文件
    try {
        const overviewPath = path.join(__dirname, 'docs', 'basics', 'overview.md');
        if (fs.existsSync(overviewPath)) {
            await converter.convertFile(overviewPath, '系统规划与管理师概述');
            console.log('✅ 单个文件转换完成');
        } else {
            console.log('⚠️ 示例文件不存在，跳过单个文件转换');
        }
    } catch (error) {
        console.error('❌ 单个文件转换失败:', error);
    }
    
    // 示例2: 批量转换目录
    try {
        const docsPath = path.join(__dirname, 'docs');
        if (fs.existsSync(docsPath)) {
            const results = await converter.convertDirectory(docsPath);
            console.log('📊 批量转换结果:', results);
        } else {
            console.log('⚠️ docs 目录不存在，跳过批量转换');
        }
    } catch (error) {
        console.error('❌ 批量转换失败:', error);
    }
}

// 如果直接运行此文件
const isMainModule = process.argv[1] && process.argv[1].endsWith('md-to-word-converter-enhanced.js');
if (isMainModule) {
    console.log('🚀 开始执行批量转换...');
    main().catch(console.error);
}

export default EnhancedMarkdownToWordConverter; 